package fem2.material;

import java.util.ArrayList;

import org.junit.Test;

import fem2.AbstractStructuralStaticDemo;
import fem2.Constraint;
import fem2.Debugger;
import fem2.Element;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshPart;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.Node;
import fem2.PatchTestT3;
import fem2.analysis.Analysis;
import fem2.analysis.NonlinearStaticAnalysis;
import fem2.element.StructuralElement;
import fem2.enu.EchoLevelType;
import fem2.enu.State;
import fem2.material.FluencyCriteria;
import fem2.material.LemaitreDamageMM;
import fem2.material.LinearIsotropicHardeningRule;
import fem2.strategies.Strategy;

public class PatchTestLemaitre extends AbstractStructuralStaticDemo {

	@Override
	public Mesh createMesh() {
		// return new PatchTestT3(0).createMesh(0.5, 0.5);
		// return new PatchTestT3(0).createMesh(0.88, 0.22);
		return new PatchTestT3(0).createMesh();
	}

	@Override
	public Model createConditions(Model m) {
		Mesh mesh = m.getMesh();

		ArrayList<Node> left_nodes = MeshUtilities.seekNodesOnSurface(mesh, 1, 0, 0);
		ArrayList<Node> bottom_nodes = MeshUtilities.seekNodesOnSurface(mesh, 0, 1, 0);
		ArrayList<Node> right_nodes = MeshUtilities.seekNodesOnSurface(mesh, 1, 0, -1);

		Constraint cx = new Constraint(false, true);
		Constraint cy = new Constraint(true, false);

		double du = 1.0;
		Constraint cu = new Constraint(false, true);
		cu.setValue(0, du);

		mesh.addConstraint(cx, left_nodes);
		mesh.addConstraint(cy, bottom_nodes);
		mesh.addConstraint(cu, right_nodes);

		return m;
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 2;
		double nu = 0.3;
		double t = 1.0;
		State ss = State.PLANE_STRAIN;
		double ft = 1.9;
		double K = 2.0;
		double s = 1.0;
		double r = 1.0;
		FluencyCriteria isoLaw = new LinearIsotropicHardeningRule(ft, K);
		MaterialModel mm = new LemaitreDamageMM(E, nu, t, 0.0, ss, isoLaw, r, s);
		return mm;
	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm) {
		Element e = new StructuralElement(mp, mm);
		e.setEchoLevel(EchoLevelType.DEBUG);
		return e;
	}

	@Test
	public void test1() {
		Model m = createModel();

		int nt = 10;
		Analysis an = new NonlinearStaticAnalysis(m, nt);
		Strategy s = an.getStrategy();
		s.setEchoLevel(EchoLevelType.OUTPUT, EchoLevelType.AUX1);

		an.run();

		postProcess(m);

		Debugger.warn("Analysis completed");
	}
}
